package com.coderman.java8.actions;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author fanchunshuai
 * @Date 2019/12/3 14
 * @Description: java 8 Stream API 学习
 * https://mp.weixin.qq.com/s?__biz=MzUzMTA2NTU2Ng==&mid=2247488394&idx=2&sn=ff911c68eed943ae9a16e5c86ca94616&key=688085f24308deb86435d56a6e8c8703e0fea81effd590b2c937519d81de375146dee80d7cb51fe6e1491ecab2a12125ad3088ac8c2870bf9715a057ddb032fb77ca3f97b4c81dfe9b028ba90e2c775b&ascene=1&uin=MjYzNzcyMTYyNw%3D%3D&devicetype=Windows+10&version=62070158&lang=zh_CN&pass_ticket=rvrkNb1KrVGsombVF989MpopsoPQhii%2FaujGAJXC1iZiWL5LltNQGL9rIssEQC%2Bh
 */
public class DataPerson {
    private String name;
    private int age;
    private String gender;

    public DataPerson() {
    }

    public DataPerson(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }


    public static List<DataPerson> getDemoList() {
        List<DataPerson> list = null;

        DataPerson wu = new DataPerson("wuqi beijing", 19, "男");
        DataPerson zhang = new DataPerson("zhangsan nanjing", 23, "女");
        DataPerson li = new DataPerson("lisi shanghai", 22, "男");
        DataPerson zhao = new DataPerson("zhao nanchang", 76, "女");
        DataPerson wang = new DataPerson("wang zhengzhou", 14, "男");
        DataPerson zhang2 = new DataPerson("zhangsan2 zhengzhou", 23, "女");
        DataPerson li3 = new DataPerson("lisi3 zhengzhou", 22, "男");
        DataPerson zhao3 = new DataPerson("zhao3 zhengzhou", 7, "女");
        DataPerson wang3 = new DataPerson("wang3 zhengzhou", 9, "男");
        list = Arrays.asList(li, wang, wang3, zhang, li3, zhao3, zhao, zhang2, wu);
        return list;
    }


    public static void main(String[] args) {
        filterSex("男");
        getUserNameList();
        getUserNameSet();
        getUserNameMap();
        getUserNameSplitList();
    }

    /**
     * java8 过滤
     * @param sex
     */
    public static void filterSex(final String sex) {
        //old
        List<DataPerson> list = new ArrayList<>();
        for (DataPerson dataPerson : getDemoList()) {
            if (dataPerson.getGender().equals(sex)) {
                list.add(dataPerson);
            }
        }
        System.out.println(list);
        //new
        List<DataPerson> newList = list.stream().filter(x -> x.getGender().equals(sex)).collect(Collectors.toList());
        System.out.println(newList);

        //多个条件过滤
        List<DataPerson> newList2 = list.stream().filter(x -> x.getGender().equals(sex) && x.getAge() > 18).collect(Collectors.toList());
        System.out.println(newList2);
    }

    /**
     * java 8取出对象中的属性为List
     */
    public static void getUserNameList(){
        //old
        List<String> list = new ArrayList<>();
        for (DataPerson dataPerson : getDemoList()) {
            list.add(dataPerson.getName());
        }
        System.out.println(list);
        //new - 1 写法1
        List<String> newList = getDemoList().stream().map(x -> x.getName()).collect(Collectors.toList());
        System.out.println(newList);

        //new - 2 写法2
        List<String> newList2 = getDemoList().stream().map(DataPerson::getName).collect(Collectors.toList());
        System.out.println(newList2);
    }

    /**
     * java 8取出对象中的属性为Set
     */
    public static void getUserNameSet(){
        //old
        List<String> list = new ArrayList<>();
        for (DataPerson dataPerson : getDemoList()) {
            list.add(dataPerson.getName());
        }
        System.out.println(list);
        //new - 1 写法1
        Set<String> newSet = getDemoList().stream().map(x -> x.getName()).collect(Collectors.toSet());
        System.out.println(newSet);

        //new - 2 写法2
        Set<String> newSet2 = getDemoList().stream().map(DataPerson::getName).collect(Collectors.toSet());
        System.out.println(newSet2);

        //new - 3 写法3 指定集合类型
        TreeSet<DataPerson> newSet3 = getDemoList().stream()
                .collect(Collectors.toCollection(TreeSet::new));
        System.out.println(newSet3);
    }

    /**
     * java 8 将list对象转成Map对象
     */
    public static void getUserNameMap(){
        //old
        Map<String,DataPerson> dataPersonMap = new HashMap<>();
        for (DataPerson dataPerson : getDemoList()) {
            dataPersonMap.put(dataPerson.getName(),dataPerson);
        }
        System.out.println(dataPersonMap);
        //new - 1 写法1 返回的Map不需要再修改的话使用HashMap即可，不用考虑线程安全问题
        Map<String,DataPerson> dataPersonMapnew  = getDemoList().stream().collect(Collectors.toMap(DataPerson::getName,o->o));
        System.out.println(dataPersonMapnew);
        //new - 2 写法2 返回的Map有需要修改的情况建议使用下面的方式，保障线程安全
        ConcurrentHashMap<String, DataPerson> dataPersonMapnew2  = (ConcurrentHashMap)getDemoList().stream().collect(Collectors.toConcurrentMap(DataPerson::getName, o->o));
        System.out.println(dataPersonMapnew2);

        //new - 3 写法3 如果确定List里面有重复数据则使用下面的方式，否则使用写法1会报错
        Map<String,DataPerson> dataPersonMapnew3  = getDemoList().stream().collect(Collectors.toMap(DataPerson::getName,o->o,(k1,k2)->k2));
        System.out.println(dataPersonMapnew3);


        //new - 4 写法4 通过对象属性中的多个值作为key,如果确定List里面有重复数据则使用下面的方式，否则使用写法1会报错
        Map<String,DataPerson> dataPersonMapnew4  = getDemoList().stream().collect(Collectors.toMap((x)->x.getName()+x.getAge(),o->o,(k1,k2)->k2));
        System.out.println(dataPersonMapnew4);


        //new - 5 写法5 将list按年龄属性分组
        Map<Integer,List<DataPerson>> dataPersonMapnew5  = getDemoList().stream().collect(Collectors.groupingBy(DataPerson::getAge));
        System.out.println(dataPersonMapnew5);

        //new - 6 写法6 将list按年龄属性分组,返回的Map有需要修改的情况建议使用下面的方式，保障线程安全
        ConcurrentMap<Integer,List<DataPerson>> dataPersonMapnew6  = getDemoList().stream().collect(Collectors.groupingByConcurrent(DataPerson::getAge));
        System.out.println(dataPersonMapnew6);

    }


    /**
     * java 8 将list对象中的属性再次分割形成新list
     */
    public static void getUserNameSplitList(){
        //old
        List<String> list = new ArrayList<>();

        for (DataPerson dataPerson : getDemoList()) {
            dataPerson.getName().split(" ");
            list.addAll(Arrays.asList(dataPerson.getName().split(" ")));
        }
        System.out.println(list);

        //new - 1 将list.dataPerson属性中的名称再次分解形成新list
        List<String> list1 = getDemoList().stream().flatMap(dataPerson -> Arrays.stream(dataPerson.getName().split(" "))).collect(Collectors.toList());
        System.out.println(list1);
        //new - 2 将list.dataPerson属性中的名称再次分解形成新list,注意这里返回的元素是Stream
        List<Stream<String>> list2 = getDemoList().stream().map(person->Arrays.stream(person.getName().split(" "))).collect(Collectors.toList());
        System.out.println(list2);

        //new - 3 使用map实现
        List<String> list3 = getDemoList().stream().map(dataPerson -> dataPerson.getName().split(" ")).flatMap(Arrays::stream).collect(Collectors.toList());
        System.out.println(list3);

        //new - 3 使用map实现--另一种方式
        List<String> list4 = getDemoList().stream().map(dataPerson -> dataPerson.getName().split(" ")).flatMap(str-> Arrays.asList(str).stream()).collect(Collectors.toList());
        System.out.println(list4);

    }



















    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }


    @Override
    public String toString() {
        return "DataPerson{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}
